{{>licenseInfo}}

package {{invokerPackage}};

import java.util.Map;
import java.util.List;
import java.util.Locale;
{{#caseInsensitiveResponseHeaders}}
import java.util.Map.Entry;
import java.util.TreeMap;
{{/caseInsensitiveResponseHeaders}}


/**
 * <p>ApiException class.</p>
 */
@SuppressWarnings("serial")
{{>generatedAnnotation}}

public class ApiException extends{{#useRuntimeException}} RuntimeException {{/useRuntimeException}}{{^useRuntimeException}} Exception {{/useRuntimeException}}{
    private static final long serialVersionUID = 1L;

    private int code = 0;
    private Map<String, List<String>> responseHeaders = null;
    private String responseBody = null;
    {{#errorObjectType}}
    private {{{errorObjectType}}} errorObject = null;
    {{/errorObjectType}}

    /**
     * <p>Constructor for ApiException.</p>
     */
    public ApiException() {}

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param throwable a {@link java.lang.Throwable} object
     */
    public ApiException(Throwable throwable) {
        super(throwable);
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param message the error message
     */
    public ApiException(String message) {
        super(message);
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param message the error message
     * @param throwable a {@link java.lang.Throwable} object
     * @param code HTTP status code
     * @param responseHeaders a {@link java.util.Map} of HTTP response headers
     * @param responseBody the response body
     */
    public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders, String responseBody) {
        super(message, throwable);
        this.code = code;
        {{#caseInsensitiveResponseHeaders}}
        Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
        for(Entry<String, List<String>> entry : responseHeaders.entrySet()){
            headers.put(entry.getKey().toLowerCase(), entry.getValue());
        }
        {{/caseInsensitiveResponseHeaders}}
        this.responseHeaders = {{#caseInsensitiveResponseHeaders}}headers{{/caseInsensitiveResponseHeaders}}{{^caseInsensitiveResponseHeaders}}responseHeaders{{/caseInsensitiveResponseHeaders}};
        this.responseBody = responseBody;
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param message the error message
     * @param code HTTP status code
     * @param responseHeaders a {@link java.util.Map} of HTTP response headers
     * @param responseBody the response body
     */
    public ApiException(String message, int code, Map<String, List<String>> responseHeaders, String responseBody) {
        this(message, (Throwable) null, code, responseHeaders, responseBody);
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param message the error message
     * @param throwable a {@link java.lang.Throwable} object
     * @param code HTTP status code
     * @param responseHeaders a {@link java.util.Map} of HTTP response headers
     */
    public ApiException(String message, Throwable throwable, int code, Map<String, List<String>> responseHeaders) {
        this(message, throwable, code, responseHeaders, null);
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param code HTTP status code
     * @param responseHeaders a {@link java.util.Map} of HTTP response headers
     * @param responseBody the response body
     */
    public ApiException(int code, Map<String, List<String>> responseHeaders, String responseBody) {
        this("Response Code: " + code + " Response Body: " + responseBody, (Throwable) null, code, responseHeaders, responseBody);
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param code HTTP status code
     * @param message a {@link java.lang.String} object
     */
    public ApiException(int code, String message) {
        super(message);
        this.code = code;
    }

    /**
     * <p>Constructor for ApiException.</p>
     *
     * @param code HTTP status code
     * @param message the error message
     * @param responseHeaders a {@link java.util.Map} of HTTP response headers
     * @param responseBody the response body
     */
    public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody) {
        this(code, message);
        {{#caseInsensitiveResponseHeaders}}
        Map<String, List<String>> headers = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
        for(Entry<String, List<String>> entry : responseHeaders.entrySet()){
            headers.put(entry.getKey().toLowerCase(), entry.getValue());
        }
        {{/caseInsensitiveResponseHeaders}}
        this.responseHeaders = {{#caseInsensitiveResponseHeaders}}headers{{/caseInsensitiveResponseHeaders}}{{^caseInsensitiveResponseHeaders}}responseHeaders{{/caseInsensitiveResponseHeaders}};
        this.responseBody = responseBody;
    }

    /**
     * Get the HTTP status code.
     *
     * @return HTTP status code
     */
    public int getCode() {
        return code;
    }

    /**
     * Get the HTTP response headers.
     *
     * @return A map of list of string
     */
    public Map<String, List<String>> getResponseHeaders() {
        return responseHeaders;
    }

    /**
     * Get the HTTP response body.
     *
     * @return Response body in the form of string
     */
    public String getResponseBody() {
        return responseBody;
    }

    /**
     * Get the exception message including HTTP response data.
     *
     * @return The exception message
     */
    public String getMessage() {
        return String.format(Locale.ROOT, "Message: %s%nHTTP response code: %s%nHTTP response body: %s%nHTTP response headers: %s",
                super.getMessage(), this.getCode(), this.getResponseBody(), this.getResponseHeaders());
    }
    {{#errorObjectType}}

    /**
     * Get the error object.
     *
     * @return Error object
     */
    public {{{errorObjectType}}} getErrorObject() {
        return errorObject;
    }

    /**
     * Get the error object.
     *
     * @param errorObject Error object
     */
    public void setErrorObject({{{errorObjectType}}} errorObject) {
        this.errorObject = errorObject;
    }
    {{/errorObjectType}}
}
